<?php
/**
 * DBClient
 *
 * @package php.db
 */

/**
 * DB 연결자에 대한 추상 클래스입니다.
 *
 * <code>
 *  // DB 연결 
 *  $db = db_('mssql', 'test_db', true);
 * 
 *  // 메타 데이타 얻어오기 
 *  $data = $db->getMetaData("table");
 *  echo $data->top(1);
 *
 *  // 프로시저 사용 
 *	$db->spName('test');
 *	$db->spBind('aaa', 'int', 3, $is_output);     
 *	$db->spBind('bbb', 'int', 3, 'return', $var); 
 *
 *	$db->spSet('aaa', 10);
 * 
 *	$db->spExecute();
 *
 *	echo $db->spGet('bbb');
 *	print_r($db->spGetParameters());
 *
 *  // DB 종료 
 *  $db->close();
 *
 * </code>
 *
 * @package php.db
 * @see DB_()
 */
abstract class DBClient extends PObject {

	/**
	 * 속성 모음 
	 *
	 * program, host, port, id, pass, db, schema, version 
	 * 
	 */
	private $__attribute = array();

	/**
	 * 접속 resource
	 *
	 * @var resource
	 */
	private $__con;

	/**
	 * ResultSet 
	 *
	 * @var resource
	 */
	private $__db_result;

	/**
	 * Statement
	 *
	 * @var resource
	 */
	private $__db_statement;


	/**
	 * 쿼리 실행 결과  
	 *
	 * @var resource
	 */
	private $__db_exec;

	
	/**
	 * 실행된 sql 저장 
	 *
	 */ 
	private $__sql_history = array();
	
	/**
	 * sql template 패스 
	 * 
	 * @var string
	 */
	const PATH_SQL = "sql/";
	
	/**
	 * db 환경설정 패스 
	 * 
	 * @var string
	 */
	const PATH_CONF = "conf/db";

	/*
	 * 생성자 
	 *
	 * 연결속성 설정 
	 *
	 * @param string|array $option  db설정 파일명 또는 db연결환경 배열 
	 */
	public function __construct($option = '', $type = 'product')  {
		if (is_string($option)) { 
			$this->setConfig($option, $type);				// ini 파일 읽어들임 
		} else if (is_array($option)){ 
			$this->set($option);					// 옵션 자체 설정 
		}
	}

	/**
	 * 소멸자 
	 * 
	 */
	public function __destruct() { 
		// db가 연결되어 있으면 db 연결을 닫는다 
		if ($this->isConnected()) { 
			$this->close();
		}
		// 메모리 해제 관련해서 함수 실행 
	}

	/**
	 * 속성 읽어오기 , getAttribute() 와 같은 역할입니다. 
	 *
	 * ex) echo $dbclient->program;
	 * 
	 * @param	string $key 연결자 변수 이름 
	 * @return	mixed
	 *
	 */
	public function __get($key) { 
		return $this->__attribute[strtolower($key)];
	}

	/**
	 * 속성 설정하기 , setAttribute() 와 같은 역할입니다. 
	 *
	 * ex) $dbclient->program = "mssql";
	 * 
	 * @param	string $key	속성 이름
	 * @param	mixed $value 속성값
	 * @return	mixed
	 *
	 */
	public function __set($key, $value) { 
		$this->__attribute[strtolower($key)] = $value;
	}

	/**
	 * 쿼리 실행에 영향을 받은 row의 수 
	 *
	 * @return	int
	 */
	public function affectedRows() { return 0; }

	/**
	 * 트랜잭션 시작 
	 *
	 * @access public
	 * @return bool 시작되었으면 true, 아니면 false 
 	 */
	public function begin() { return true; }

	/**
	 * 연결
	 * 
     * @return DBClient 연결자 객체
	 */
	public function connect() 
	{
		// 연결자 저장
		$this->setConnection($this->_connect());

		// 옵션 실행 , 각각의 DB에 맞게 구현 
		if ($this->getConnection()) $this->runOption();

		// 비밀번호 숨김
		$this->id	= "";
		$this->pass = "";

		return $this;
	}

	/**
	 * 옵션 실행 
	 *
	 * 연결자 구성이외의 설정된 옵션을 자동으로 실행한다. 
	 * 
	 * DB에 맞게 구성해주세요. 
	 * 
	 */
	public function runOption() { 
		return true;
	}

	/**
	 * 연결 resource 반환
	 * 
     * @return resource
	 */
	public function getConnection() { 
		return $this->__con;
	}

	/**
	 * 연결 resource 설정
	 * 
	 */
	public function setConnection($con) { 
		$this->__con = $con;
	}

	/**
	 * 처리 결과 리턴 
	 * 
     * @return resource
	 */
	public function getExecute() { 
		return $this->__db_exec;
	}

	/**
	 * 처리결과 설정
	 * 
	 */
	public function setExecute($exec) { 
		$this->__db_exec = $exec;
	}


	/**
	 * 쿼리 실행한 결과 
	 * 
	 * @return resource 
	 */
	public function getResult($result = null) {
		return ($result) ? $result : $this->__db_result;
	}

	/**
	 * 기본 결과셋을 설정
	 * 
	 * @param resource $result 결과셋
	 */
	public function setResult($result) { 
		$this->__db_result = $result;
	}

	public function getStatement() { 
		return $this->__db_statement;
	}

	public function setStatement($stmt) { 
		$this->__db_statement = $stmt;
	}


	/**
	 * commit 
	 * 
	 */
	public function commit() { }


	/**
	 * 연결닫기
	 * 
	 * @return bool 
	 */
	public function close()
	{ 
		return true;
	}

	/**
	 * 연결자 생성 패턴 
	 * 
	 * @static 
	 * @param	string $dbClass	database 종류 (mysql, mssql, oracle, progres, cubrid, sqlite)
	 * @param string|array $db db설정 파일명 또는 db연결환경 배열 
	 * @param	bool $isConnect database 연결 여부 , 연결이면 true , 기본값 false 
	 * @return	DBClient		DBClient 상속 클래스
	 */
	public static function createConnector($dbClass, $db, $isConnect = false, $type = 'default') {

		$obj = null;

		if (class_exists($dbClass)) { 
			$obj = new $dbClass($db, $type);

			if ($isConnect) $obj->connect();
		} 

		return $obj;
	}

	/**
	 * DBData 객체 생성 
	 * 
	 * @param	resource $resource	결과 리소스
	 * @return	DBData
	 */
	public function createData($result) {
		// 기본적으로 Data 클래스를 사용하고 
		// Data 클래스를 상속한 다른 Data 클래스를 사용하면 된다. 

		$data = new DBData($this);

		if (!$result)
			return $data;

		$data->setFields($this->getFieldList($result));
		//$data->setTypeList($this->getFieldTypeList($result));
		$data->setRows($this->fetchAll($result));

		return $data;
	}



	/**
	 * 테이블 삭제 
	 * 
	 * @param unknown_type $table
	 * @return unknown_type
	 * @deprecated
	 */
	public function deleteFrom($table) { 
		return $this->query("delete from {$table}");
	}

	/**
	 * 에러 리턴
	 * 
	 */
	public function error() { return ""; } 

	/**
	 * 각각 DB별 문자열 escape	
	 * 
	 * @param string $str  escape 될 문자열 
	 * @return string escape 된 문자열
	 */
	public function escape($str) { 
		return str_replace("'", "''", $str);
	}

	/**
	 * 전체 레코드 가져오기
	 *
	 * @param	resource $result 결과 셋
	 * @return	array	레코드배열 
	 */
	public function fetchAll($result) {
		$temp = array();

		while($row = $this->fetch($result)) { 
			$temp[] = array_change_key_case($row, CASE_LOWER);
		}
		
		return $temp;	
	} 


	/**
	 * DBData  구함
	 * 
	 * @param	string $query DB query
	 * @param	boolean $isOne 인덱스 한칸 옮기기
	 * @return	DBData 
	 */
	public function getData($query, $isOne = false) 
	{
		if ($query instanceof Data) { 
			return $query;
		}
		
		$this->query($query);

		$data = $this->createData($this->getResult());

		if (!$this->getResult())  
			$this->free($this->getResult());

		if ($isOne) 
			$data->next();

		return $data;
	}
	
	/**
	 * paging 된 DBData 얻어오기 
	 * 
	 * @param string $query
	 * @param int $page default 1 
	 * @param int $count default 10 
	 * @return DBData
	 */
	abstract function getPageData($query, $page = 1, $count = 10) ;
	
	/**
	 * 한개짜리 Record 얻어올 때사용 
	 * 
	 * @param string $query
	 * @param string $baseClass
	 * @return DBData
	 */
	public function getOne($query) { 
		return $this->getData($query, true);
	}
	
	/**
	 * sql id 로 쿼리 실행 
	 * 
	 * @param string $id sql template id 또는 동적 sql
	 * @param array $param
	 * @return int
	 */
	public function sql($id, $param = array()) { 
		if ($this->checkTemplateId($id)) { 
			return $this->query($this->getSqlTemplate($id, $param));
		} else { 
			return $this->query($id);
		}
	}
	
	/**
	 * sql id 로 DBData 얻어오기  
	 * 
	 * @param string $id 
	 * @param array $param
	 * @return DBData
	 */
	public function sqlData($id, $param = array()) { 
		return $this->getData($this->getSqlTemplate($id, $param), false);
	}
	
	/**
	 * sqlData 축약형
	 * 
	 * @param string $id sql template id 또는 동적 sql
	 * @param array $param
	 * @return DBData
	 */
	public function data($id, $param = array()) {
		if ($this->checkTemplateId($id)) { 
			return $this->sqlData($id, $param);
		} else { 
			return $this->getData($id, false);
		}
	}
	
	/**
	 * sql id 로 페이징된 DBData 얻어오기 
	 * 
	 * @param string $id
	 * @param array $param
	 * @return DBData
	 */
	public function sqlPage($id, $param = array()) { 
		return $this->getPageData($this->getSqlTemplate($id, $param), d_($param['page'], 1), d_($param['count'], 10));
	}
	
	/**
	 * sqlPage 축약형
	 * 
	 * @param string $id  sql template id 또는 동적 sql 
	 * @param array $param
	 * @return DBData
	 */	
	public function page($id, $param = array()) {
		if ($this->checkTemplateId($id)) {  
			return $this->sqlPage($id, $param);
		} else { 
			return $this->getPageData($id, d_($param['page'], 1), d_($param['count'], 10));
		}	
	}

	/**
	 * sql id 로 DBData 얻어오기  
	 * 
	 * @param string $id
	 * @param array $param
	 * @return DBData
	 */
	public function sqlOne($id, $param = array()) { 
		return $this->getOne($this->getSqlTemplate($id, $param));
	}
	
	/**
	 * sqlOne 축약형  
	 * 
	 * @param string $id
	 * @param array $param
	 * @return DBData
	 */
	public function one($id, $param = array()) { 
		if ($this->checkTemplateId($id)) { 
			return $this->sqlOne($id, $param);
		} else { 
			return $this->getOne($id);
		}
	}
	
	/**
	 * 일반쿼리 페이지 계산
	 *
	 * count(*) 의 alias로 cnt 를 지정해야 함 .
	 * 
	 * @param string $id
	 * @param array $param
	 * @return array
	 * @see DBClient::getPageCountQuery
	 */
	public function sqlPageCount($id, $param = array()) { 
		return $this->getPageCountQuery($this->getSqlTemplate($id, $param), d_($param['limitPage'], 10), d_($param['limitBlock'], 10));
	}
	
	/**
	 * sqlPageCount 축약형
	 * 
	 * @param string $id
	 * @param array $param
	 * @return array
	 * @see DBClient::sqlPageCount
	 */	
	public function pageCount($id, $param = array()) { 
		return $this->sqlPageCount($id, $param);
	}	
	
	/**
	 * 템플릿 존재하는지에 대한 여부 체크 
	 * 
	 * @param string $id
	 * @return bool
	 */
	public function checkTemplateId($id) { 
		$filename = str_replace('.', '/', $id).".php";
		
		$path = LIB.self::PATH_SQL.$filename;
		
		return file_exists($path);
	}

	/**
	 * result set 이 설정된 상태에서 바로 DBData 객체를 구함 
	 * 
	 * @param bool $isOne true : 한칸전진 
	 * @param string $baseClass 클래스 이름 
	 * @return DBData
	 */
	public function getBindData($isOne = false) {

		$data = $this->createData($this->getResult());

		if ($isOne) 
			$data->next();

		return $data;
	}

	/**
	 * 페이지 계산
	 * 
	 * @param	int $total 전체 개수
	 * @param	int $limitPage 페이지 당 리스트 숫자
	 * @param	int $limitBlock 블럭당 페이지 숫자
	 * @param	int $currentPage 현재 페이지 
	 * @return	array		count : 전체숫자, page : 페이지 수, block : 블럭 수, start : 페이시 시작 번호  
	 */
	public function getPageCount($total, $limitPage, $limitBlock, $currentPage = 1) { 
		$count	= $total;
		$page	= ceil($count/$limitPage);
		$block	= ceil($page/$limitBlock);
		$start  = $count - ($currentPage - 1) * $limitPage ;		
		$end  = $start - $limitPage ;

		if ($end <= 1) { 
			$end = 1;
		}

		$temp = array(
			'count' => $count, 
			'page' => $page, 
			'block' => $block,
			'start' => $start,
			'end' => $end
		);

		return $temp;		
	}

	/**
	 * 서브쿼리 페이지 계산
	 * 
	 * @param	string $sql	서브쿼리 대상 
	 * @param	int $limitPage 페이지 당 리스트 숫자
	 * @param	int $limitBlock 블럭당 페이지 숫자
	 * @return	array count : 전체숫자, page : 페이지 수, block : 블럭 수 
	 */
	public function getPageCountSubquery($sql, $limitPage, $limitBlock) {
		$sql = "SELECT COUNT(*) as cnt FROM ( $sql )";

		return $this->getPageCountQuery($sql, $limitPage, $limitBlock);
	}

	/**
	 * 일반쿼리 페이지 계산
	 *
	 * count(*) 의 alias로 cnt 를 지정해야 함 .
	 * 
	 * @param	string $sql	일반쿼리 대상 
	 * @param	int $limitPage 페이지 당 리스트 숫자
	 * @param	int $limitBlock	블럭당 페이지 숫자
	 * @return	array	count : 전체숫자, page : 페이지 수, block : 블럭 수 
	 */
	public function getPageCountQuery($sql, $limitPage, $limitBlock) {
		$data = $this->getData($sql, true);

		return $this->getPageCount($data->get('cnt', 0), $limitPage, $limitBlock);
	}

	/**
	 * 실행되어진 쿼리에 대해서 필드리스트를 가지고 온다. 
	 * DBData객체를 만들 때 사용되어짐  
	 *
	 * @param	resource $result 쿼리 실행 결과 
	 * @return	array			
	 */
	public function getFieldList($result) {
		// 필드 리스트 얻어오기 
		$ncols = $this->getFieldCount($result);

		$arr = array();
		for ($i = 0; $i < $ncols; $i++) {
			$arr[] = $this->getFieldName($result, $i);
		}		

		return $arr;
	}



	/**
	 * 실행되어진 쿼리에 대해서 필드의 타입 리스트를 가지고 온다. 
	 * DBData객체를 만들 때 사용되어짐  
	 *
	 * @param	resource $result 쿼리 실행 결과 
	 * @return	array			
	 */
	public function getFieldTypeList($result) { 
		// 필드 리스트 얻어오기 
		$ncols = $this->getFieldCount($result);

		$arr = array();
		for ($i = 0; $i < $ncols; $i++) {
			$arr[] = $this->getFieldType($result, $i);
		}		

		return $arr;
	}

	/**
	 * 필드 타입(자료형)별 php용 전용 상수 얻어오기 
	 *
	 * @param string $type 타입문자열 
	 * @return int|string PHP상수
	 */
	public function getTypeConstant($type) { 
		return $type;
	}

	/**
	 * 필드 타입(자료형)별 DB에 입력될 수 있는 문자열 얻어오기 
	 *
	 * @param string $type 타입문자열 
	 * @param mixed $value 입력값
	 * @param boolean $is_null 널을 체크할 것인지 여부 , true 널체크, false 널 체크 안함 
	 * @return string 변환된 문자열
	 */
	public function getTypeString($type, $value, $is_null = false ) {
		return ($is_null & is_null($value)) ? 'NULL' : sprintf("'%s'", $this->escape($value));
	}

	/**
	 * getTypeString 별칭 
	 *
	 * @param string $type 타입문자열 
	 * @param mixed &$value 입력값
	 * @param boolean $is_null 널을 체크할 것인지 여부 , true 널체크, false 널 체크 안함 
	 * @return string 변환된 문자열
	 */	
	public function ts($type, &$value, $is_null = false ) { 
		$value = $this->getTypeString($type, $value, $is_null);

		return $value;
	}

	/**
	 * 통합 메타 데이타 얻어오기
	 * 
	 * <pre>
	 * 파일 경로 : php/db/meta/
     * 파일 형식 : {메타타입}Data_{program}{version}.php 
	 * </pre>
	 *
	 * <code>
	 * 	    // 현재 연결된 db의 사용자 테이블 리스트를 Data객체로 반환
	 * 		$db->getMetaData('table');					
	 * 
	 *		// 주어진 테이블에 대해서 인덱스 리스트를 Data객체로 반환
	 *		$db->getMetaData('index', '테이블이름');	
	 * 
	 * 		// 주어진 테이블에 대해서 컬럼 리스트를 Data객체로 반환
	 *		$db->getMetaData('column', '테이블이름');	
	 * 
	 * </code>
	 *
	 * @param string $meta_type 얻어올 메타데이타 타입 형태 (table, database, column, index, job, param, proc, view, serial, etc)
	 * @param string $object 객체 이름 
	 * @param array $option  그 외 옵션, DB마다 틀림 
	 * @return	DBData 
	 */
	public function getMetaData($type = 'table', $object = '', $option = array()) {
		// 파일 이름 설정
		$id = sprintf("meta.%s.%s.%s", strtolower($this->program), $this->version, strtolower($type) );

		// 메타Data 필요한 정보 설정
		$param = array(
			'schema'	=> $this->escape($this->schema),
			'object'	=> $this->escape($object),
			'db'		=> $this->escape($this->db),
			'option'	=> $option
		);

		return $this->sqlData($id, $param);
	}
	
	/**
	 * getMetaData 축약형
	 * 
	 * 
	 * @param string $meta_type 얻어올 메타데이타 타입 형태 (table, database, column, index, job, param, proc, view, serial, etc)
	 * @param string $object 객체 이름 
	 * @param array $option  그 외 옵션, DB마다 틀림 
	 * @return	DBData 
	 */
	public function meta($type = 'table', $object = '', $option = array()) {
		return $this->getMetaData($type, $object, $option);	
	}
	
	/**
	 * SQL 템플릿 생성 
	 *
	 * @param string $id sql 파일 아이디 
	 * @param array $data sql 템플릿을 생성할 때 필요한 데이타 
	 * @return string 
	 */
	public function getSqlTemplate($id, $param = array()) { 
		$filename = str_replace('.', '/', $id).".php";
		
		$path = LIB."sql/".$filename;
		
		if (file_exists($path)) { 
			return include $path;
		} else { 
			trigger_error("file not exists : ".$id, E_USER_ERROR);
			return ""; 
		}
	}

	/**
	 * getSqlTemplate 축약형 
	 * 
	 * @param string $id sql 파일 아이디 
	 * @param array $data sql 템플릿을 생성할 때 필요한 데이타 
	 * @return string 
	 * @see DBClient::getSqlTemplate()
	 */
	public function template($id, $param = array()) { 
		return $this->getSqlTemplate($id, $param);
	}
	
	/**
	 * 현재 DB 확인하기 
	 *
	 * <code>
	 * if ($dbclient->is('mssql')) { 
	 *    echo "database is mssql";
	 * } 
	 *
	 * if ($dbclient->is('mysql', '5')) { 
     *    echo "current version : mysql 5" ;
	 * }
	 * </code>
	 *
	 * @param	string $db_name	데이타베이스 종류 (mysql, mssql, oracle, postgres, cubrid, sqlite)
	 * @param	string $version	속성값
	 * @return	boolean			
	 *
	 */
	public function is($db_name, $version = '') { 
		if (!$version) { 
			return ($this->program == strtolower($db_name));
		} else { 
			return ($this->program == strtolower($db_name) && $this->version == $version);
		}
	}

	/**
	 * 연결되어 있는지 여부를 알려줌
	 *
	 * @access public 
	 * @return bool 연결되어 있으면 true, 아니면 false 
	 */
	public function isConnected() { 
		return ($this->getConnection()) ? true : false ;
	}

	/**
	 * rollback
	 * 
	 */
	public function rollback() { }


	/**
	 * result set 이동 
	 *
	 * @param	int $count 이동할 row의 수 
	 */
	public function seek($count) { }

	/**
	 * 연결설정
	 * 
	 * @param	array $option 연결자 변수 이름 
	 *
	 */
	public function set($option = array())
	{
		$this->__attribute = $option;
	}

	/**
	 * 연결설정,  /php/db/conf/{name}.ini 파일에 설정 저장 
	 * 
	 * program : db프로그램 
	 * host : db 주소 <br >
	 * port : 포트 <br >
	 * id   : 아이디 <br > 
	 * pass : 비밀번호  <br >
	 * db   : db 이름  <br >
	 * version : 버전 <br >
	 * schema  : 스키마  <br >
	 * 
	 * db 마다 조금씩 틀립니다. 
	 * 
	 * @param string $name 연결자 변수 이름 
	 * @param string $type $type 에 맞는 연결자 설정 
	 */
	public function setConfig($name, $type = 'product') { 
		$name		= strtolower($name);

		$path = LIB.self::PATH_CONF."{$name}.ini";

		if (!file_exists($path)) return; 

		$arr = parse_ini_file($path, true);

		$this->set($this->getProperty($arr[$type]));
	}

	/**
	 * 연결속성 설정
	 * 
	 * @param  array $arr db 설정 변수 
	 * @return array 변수 값을 필터링 하고 넘겨준다. 
	 */
	public function getProperty($arr) { 

		foreach ($arr as $key => $value) { 
			$arr[$key]	 = str_replace("{LIB}", LIB, $value);
		}

		return $arr;
	}


	/**
	 * 연결 리소스 리턴
	 * 
	 * @return	resource		연결 리소스 
	 */
	abstract protected function _connect();

	/**
	 * 메모리 해제
	 *
	 * @param	resource $result 결과 셋 
	 */
	abstract public function free($result) ;


	/**
	 * 레코드 가져오기
	 *
	 * @param	resource $result 결과 셋
	 * @return	array
	 */
	abstract public function fetch($result) ;


	/**
	 * 필드 개수 가지고 오기
	 *
	 * @param	resource $result 결과 셋
	 * @return	int
	 */
	abstract public function getFieldCount($result) ;

	/**
	 * 필드 이름 가지고 오기 
	 *
	 * @param	resource $result 결과 셋
	 * @param	int $i 필드 offset, 0-based number
	 * @return	string		필드 이름 
	 */
	abstract public function getFieldName($result, $i) ;

	/**
	 * 필드 타입 가지고 오기 
	 *
	 * @param	resource $result 결과 셋
	 * @param	int $i 필드 offset, 0-based number
	 * @return	string		필드 타입 이름 
	 */
	abstract public function getFieldType($result, $i);

	/**
	 * 쿼리 실행하기
	 *
	 * @param	string $sql	sql 쿼리문
	 * @return	resource		결과 셋, 없을 경우는 false 
	 */
	abstract public function query($sql) ;

	
	/**
	 * sql history 기록하기 
	 *
	 * @param string $sql sql 쿼리문
	 */
	public function addSql($sql) { 
		$this->__sql_history[] = $sql;
	}

	/**
	 * 실행된 sql 얻어오기 
	 *
	 * @param int $num 실행된 sql 인덱스 번호 
	 * @return string sql 
	 */
	public function getSql($num = '') { 
		$index = ($num == '') ? sizeof($this->__sql_history)-1 : 0;

		return $this->__sql_history[$index];
	}

	/**
	 * 실행된 sql 출력하기 
	 */
	public function printSql() { 
		echo "<pre>".print_r($this->__sql_history, true)."</pre>";
	}

	/**
	 * prepare
	 * 
	 * 상속받은 클래스에서 구현 
	 * 
	 */
	public function prepare($sql) { 

	}

	/**
	 * prepare된 구문을 바인딩 한다. 
	 *
	 * 상속받은 클래스에서 구현
	 * 
	 * @param string $name 바인딩 이름 
	 * @param string $type 바인딩될 타입, 데이타베이스 마다 틀림 
	 * @param string $output output 형태, in, out, inout, return 
	 * @param int $length 데이타길이, -1은 길이제한 없음
	 * @param mixed $value 저장될 데이타 또는 output 변수에 저장될 데이타
	 *
	 *  
	 */
	public function bind($name, $type = '', $output = 'in', $length = -1, &$value = null ) { 

	}

	/**
	 * prepare된 구문을 실행한다. 
	 *
	 * 상속받은 클래스에서 구현 
	 */
	public function execute() { 

	}
	
	/**
	 * 프로시저를 실행할 객체 리턴 , 하위에서 구현해야합니다. 
	 * 
	 * @param string $name
	 * @param mixed $option
	 * @return DBProc
	 */
	public function createProc($name, $option = '') { 
		return null;
	}

	/**
	 * prepare 된 구문 메모리 해제 
	 *
	 * 상속받은 클래스에서 구현 
	 */ 
	public function freeStatement($stmt) { } 

}

?>